Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | import { eq } from 'drizzle-orm' import { NextResponse } from 'next/server' import { db } from '@/db' import type { GameStatsBreakdown } from '@/db/schema/player-stats' import { playerStats } from '@/db/schema/player-stats' import { players } from '@/db/schema/players' import type { GetPlayerStatsResponse, PlayerStatsData } from '@/lib/arcade/stats/types' import { withAuth } from '@/lib/auth/withAuth' import { getUserId } from '@/lib/viewer' /** * GET /api/player-stats/[playerId] * * Fetches stats for a specific player (must be owned by current user). */ export const GET = withAuth(async (_request, { params }) => { try { const { playerId } = (await params) as { playerId: string } // 1. Authenticate user const userId = await getUserId() if (!userId) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } // 2. Verify player belongs to user const player = await db .select() .from(players) .where(eq(players.id, playerId)) .limit(1) .then((rows) => rows[0]) if (!player) { return NextResponse.json({ error: 'Player not found' }, { status: 404 }) } if (player.userId !== userId) { return NextResponse.json( { error: 'Forbidden: player belongs to another user' }, { status: 403 } ) } // 3. Fetch player stats const stats = await db .select() .from(playerStats) .where(eq(playerStats.playerId, playerId)) .limit(1) .then((rows) => rows[0]) const playerStatsData: PlayerStatsData = stats ? convertToPlayerStatsData(stats) : createDefaultPlayerStats(playerId) // 4. Return response const response: GetPlayerStatsResponse = { stats: playerStatsData, } return NextResponse.json(response) } catch (error) { console.error('❌ Failed to fetch player stats:', error) return NextResponse.json( { error: 'Failed to fetch player stats', details: error instanceof Error ? error.message : String(error), }, { status: 500 } ) } }) /** * Convert DB record to PlayerStatsData */ function convertToPlayerStatsData(dbStats: typeof playerStats.$inferSelect): PlayerStatsData { return { playerId: dbStats.playerId, gamesPlayed: dbStats.gamesPlayed, totalWins: dbStats.totalWins, totalLosses: dbStats.totalLosses, bestTime: dbStats.bestTime, highestAccuracy: dbStats.highestAccuracy, favoriteGameType: dbStats.favoriteGameType, gameStats: (dbStats.gameStats as Record<string, GameStatsBreakdown>) || {}, lastPlayedAt: dbStats.lastPlayedAt, createdAt: dbStats.createdAt, updatedAt: dbStats.updatedAt, } } /** * Create default player stats for new player */ function createDefaultPlayerStats(playerId: string): PlayerStatsData { const now = new Date() return { playerId, gamesPlayed: 0, totalWins: 0, totalLosses: 0, bestTime: null, highestAccuracy: 0, favoriteGameType: null, gameStats: {}, lastPlayedAt: null, createdAt: now, updatedAt: now, } } |